<script setup>
import ChatMessage from '@/views/chat/components/ChatMessage.vue'
import ChatInput from '@/views/chat/components/ChatInput.vue'
import {ref, computed} from "vue"
import moment from "moment"
import {defaultChat, httpGetLastId} from "@/api/chat.js"
import {ElMessage} from "element-plus"
import { isObjectJson } from '@/utils/index.js'

const histories = ref([])
const isOutAct = ref(false)
const aiOutput = ref('')
const disable = ref(false)
const conversationId = ref(0)
let controller = null

const aiHistories = computed(() => {
  const h = [
      {
        content: 'Hi，欢迎使用 AI 智能问答，可以为你解答笔记内记录的任何问题！',
        role: 'assistant',
        docs: '',
        knowledge_id: 0,
        file_names: [],
        time: moment().format("YYYY-MM-DD HH:mm:ss")
      }
  ]
  return h.concat(histories.value)
})

const httpHistories = () => {
  const list = histories.value.slice(-8)
  return list.map(item => {
    const {role, content, docs} = item
    return {
      role,
      content: content.replaceAll("{", "{{").replaceAll("}", "}}"),
      docs: '', // !docs ? '' : docs.replaceAll("{", "{{").replaceAll("}", "}}")
    }
  })
}

/**
 * @param {String} content
 */
const requestChat = (content) => {
  disable.value = true
  defaultChat({
    message: content,
    conversation_id: conversationId.value ? conversationId.value : undefined,
    history: httpHistories(),
    score_threshold: 0.7,
    with_note: 1
  }).then(({reader, header, control}) => {
    controller = control
    if (header.get('X-Custom-Header')) {
      let docs = ''
      if (header.get('Content-Documents')) {
        docs = decodeURIComponent(header.get('Content-Documents'))
        if (!docs) {
          docs = ''
        }
      }
      isOutAct.value = true
      conversationId.value = parseInt(header.get('X-Custom-Header'))
      histories.value.push({
        role: 'user',
        docs: docs,
        file_names: [],
        knowledge_id: 0,
        content: content,
        time: moment().format("YYYY-MM-DD HH:mm:ss")
      })
    }
    handleReader(reader)
  }).catch(() => {
    isOutAct.value = false
    disable.value = false
  })
}

const handleReader = async (reader) => {
  let d, v
  try {
    const {value, done} = await reader.read()
    d = done
    v = value
  } catch (e) {
    d = true
  }
  const decoder = new TextDecoder()
  if (!d) {
    let data = decoder.decode(v.buffer)
    aiOutput.value += data
    await handleReader(reader)
  } else {
    if (v) {
      let data = decoder.decode(v.buffer)
      aiOutput.value += data
    }
    const json = isObjectJson(aiOutput.value)
    if (json !== false && json.code !== 200) {
      aiOutput.value = ''
      disable.value = false
      isOutAct.value = false
      ElMessage.error(json.message)
    } else {
      if (aiOutput.value) {
        const {hid} = await httpGetLastId(conversationId.value).catch(() => {
          return {hid: 0}
        })
        histories.value.push({
          id: hid,
          content: aiOutput.value,
          knowledge_id: 0,
          role: 'assistant',
          file_names: [],
          time: moment().format("YYYY-MM-DD HH:mm:ss")
        })
      }
      aiOutput.value = ''
      isOutAct.value = false
      disable.value = false
      // await getQuestions()
    }
  }
}

</script>

<template>
  <div>
    <chat-message
        :histories="aiHistories" :is-out-act="isOutAct" :ai-output="aiOutput" :disable="disable"
        :show-tools="false"
    />
    <chat-input
        :disable="disable" :show-tools="false" :on-submit="requestChat"
    />
  </div>
</template>

<style scoped lang="scss">
:deep(.sect) {
  width: 100% !important;
  height: calc(100% - 70px) !important;
  overflow: hidden;
}

:deep(.chat-section) {
  width: calc(100% + 50px);
  height: 100%;
  position: relative;
  left: 0;
  overflow-x: hidden;
  overflow-y: auto;
}
:deep(.chat-message-box>.user) {
  width: calc(100% - 50px);
}
:deep(.chat-message-box>.assistant) {
  width: calc(100% - 50px);
}
</style>